package com.tyk.bookstore.back.payment.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tyk.bookstore.back.common.core.util.ObjUtil;
import com.tyk.bookstore.back.member.model.dto.Member4PaymentDto;
import com.tyk.bookstore.back.member.service.MemberApiService;
import com.tyk.bookstore.back.payment.manager.excel.model.AmountLogExcelVo;
import com.tyk.bookstore.back.payment.model.entity.AmountLogDo;
import com.tyk.bookstore.back.payment.model.query.AmountLogAddQuery;
import com.tyk.bookstore.back.payment.model.query.AmountLogPageQuery;
import com.tyk.bookstore.back.payment.model.query.AmountLogUpdateQuery;
import com.tyk.bookstore.back.payment.model.vo.AmountLogPageVo;
import com.tyk.bookstore.back.payment.model.vo.AmountLogVo;
import com.tyk.bookstore.back.payment.repository.AmountLogRepository;
import com.tyk.bookstore.back.payment.service.AmountLogService;
import com.tyk.bookstore.back.payment.util.MapStructPayment;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author tyk
 * @description 系统余额变更日志
 */
@Service
@RequiredArgsConstructor

public class AmountLogServiceImpl implements AmountLogService {

    private final AmountLogRepository amountLogRepository;
    private final MemberApiService memberApiService;
    private final MapStructPayment mapStructPayment;

    @Override
    public AmountLogVo getById(Long id) {
        AmountLogDo amountLog = amountLogRepository.selectById(id);
        return mapStructPayment.toAmountLogVo(amountLog);
    }

    @Override
    public AmountLogPageVo getPage(AmountLogPageQuery query) {
        // 查询
        Page<AmountLogDo> page = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<AmountLogDo> w = buildPageQueryWrapper(query);
        amountLogRepository.selectPage(page, w);
        AmountLogPageVo pv = mapStructPayment.toAmountLogPageVo(page);
        // 补充会员信息
        Set<Long> midSet = page.getRecords().stream().map(AmountLogDo::getMemberId).collect(Collectors.toSet());
        Map<Long, Member4PaymentDto> mMap = memberApiService
                .getMember4PaymentDtoListByIdSet(midSet)
                .stream().collect(Collectors.toMap(
                        Member4PaymentDto::getId,
                        it -> it
                ));
        pv.getRecords().forEach(it -> {
            Member4PaymentDto dto = mMap.get(it.getMemberId());
            it.setMemberName(dto.getNickname())
                    .setMemberAccount(dto.getAccount());
        });
        // 返回
        return pv;
    }


    @Override
    public void add(AmountLogAddQuery query) {
        AmountLogDo amountLog = mapStructPayment.toAmountLogDo(query);
        amountLogRepository.insert(amountLog);
    }

    @Override
    public void updateById(AmountLogUpdateQuery query) {
        AmountLogDo amountLog = mapStructPayment.toAmountLogDo(query);
        amountLogRepository.updateById(amountLog);
    }

    @Override
    public void deleteById(Long id) {
        amountLogRepository.deleteById(id);
    }

    @Override
    public void deleteBatchByIdSet(Set<Long> idSet) {
        amountLogRepository.deleteBatchIds(idSet);
    }

    @Override
    public List<AmountLogExcelVo> getAmountLogExcelVoList(AmountLogPageQuery query) {
        LambdaQueryWrapper<AmountLogDo> w = buildPageQueryWrapper(query);
        List<AmountLogDo> doList = amountLogRepository.selectList(w);
        return mapStructPayment.toAmountLogExcelVoList(doList);
    }


    /**
     * 构建分页查询Wrapper
     */
    private LambdaQueryWrapper<AmountLogDo> buildPageQueryWrapper(AmountLogPageQuery query) {

        LambdaQueryWrapper<AmountLogDo> w = new LambdaQueryWrapper<>();

        // 类型
        w.eq(query.getType() != null, AmountLogDo::getType, query.getType());

        // 变更值
        w.ge(query.getModificationFrom() != null, AmountLogDo::getModification, query.getModificationFrom());
        w.le(query.getModificationTo() != null, AmountLogDo::getModification, query.getModificationTo());

        // 记录时间
        w.ge(query.getCreateTimeFrom() != null, AmountLogDo::getCreateTime, query.getCreateTimeFrom());
        w.le(query.getCreateTimeTo() != null, AmountLogDo::getCreateTime, query.getCreateTimeTo());

        // 会员ID
        if (ObjUtil.notBlank(query.getMemberKeyword())) {
            List<Long> midList = memberApiService.getIdListByKw(query.getMemberKeyword());
            w.in(AmountLogDo::getMemberId, midList);
        }

        // 时间排序
        w.orderBy(true, false, AmountLogDo::getCreateTime);

        return w;
    }

}

